package cn.ryh.fileupload.controller;

import cn.ryh.fileupload.entity.Failure;
import cn.ryh.fileupload.entity.Result;
import cn.ryh.fileupload.entity.Success;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.*;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

/**
 * @ClassName FileUploadController
 * @Description TODO
 * MultipartHttpServletRequest: 继承于HttpServletRequest以及MultipartRequest.
 * 其中MultipartRequest中定义了相关的访问操作. MultipartHttpServletRequest重写
 * 了HttpServletRequest中的方法, 并进行了扩展. 如果以HttpServletRequest来接收参
 * 数, 则需要先将其转为MultipartHttpServletRequest类型
 * MultipartHttpServletRequest request = (MultipartHttpServletRequest) HttpServletRequest;
 * 那么对于后台接收到的是什么, 可以这么理解, 就是一个Map的形式(实际上它后台真的是以Map来存储的).
 * 这个Map的Key是什么呢? 就是上面<input>标签中的name=""属性. Value则是我们刚才上传的
 * 文件, 通过下面的示例可以看出每一个Value就是一个包含对应文件集合的List
 * 传到后台接收到的Map就是这样:
 * fileList: 文件2, 文件3, 文件4
 * 虽然从方法名的表面意义来看是得到文件名, 但实际上这个文件名跟上传的文件本身并没有什么关系.
 * 刚才说了这个Map的Key就是<input>标签中的name=""属性, 所以得到的也就是这个属性的值
 *  multipartFile.transferTo(new File(newName));
 *  相当于
 *  BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(newName)));
 *  out.write(multipartFile.getBytes());
 *  out.flush();
 *  out.close();
 *
 * @Author RaoYH
 */
@Controller
@RequestMapping("/fileUploadController")
public class FileUploadController {
    /**
     * 访问updateLoad页面
     *
     * @return
     */
    @RequestMapping(value = "/upload")
    public String updateLoad() {
        return "upload";
    }

    /**
     * 访问multiFileUpload页面
     * @return
     */
    @RequestMapping(value = "/multiFileUpload")
    public String multiFileUpload() {
        return "multiFileUpload";
    }
    /**
     * 单文件上传
     *
     * @param file
     * @return
     */
    @RequestMapping("/handleFileUpload")
    @ResponseBody
    public Result handleFileUpload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return new Failure("上传失败，文件不能为空");
        } else {
            try {
                BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(
                        new File(getNewFileName(file.getOriginalFilename()))));
                out.write(file.getBytes());
                out.flush();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
                return new Failure("上传失败" + e.getMessage());
            }
            return new Success("上传成功");
        }
    }

    /**
     * 多文件上传
     *
     * @return
     */
    @RequestMapping(value = "/handleMultiFileUpload")
    @ResponseBody
    public Result handleMultiFileUpload(MultipartHttpServletRequest request) throws IOException {

        Iterator<String> fileNames = request.getFileNames();
        while (fileNames.hasNext()) {
            /**
             * request.getFiles(fileName)方法即通过fileName这个Key, 得到对应的文件
             * 集合列表. 只是在这个Map中, 文件被包装成MultipartFile类型
             */
            List<MultipartFile> fileList = request.getFiles(fileNames.next());
            if (fileList.size() > 0) {
                //遍历文件列表
                Iterator<MultipartFile> fileIte = fileList.iterator();
                while (fileIte.hasNext()) {
                    //获得每一个文件
                    MultipartFile multipartFile = fileIte.next();
                    //获得原文件名
                    String originalFilename = multipartFile.getOriginalFilename();
                    //获取新文件名
                    String newName = getNewFileName(originalFilename);
                    //获取项目根路径
                    //String path = new File("").getCanonicalPath();
                    /**
                     * MultipartFile提供了void transferTo(File dest)方法,
                     * 将获取到的文件以File形式传输至指定路径.
                     */
                    multipartFile.transferTo(new File(newName));
                }
            }
        }
        return new Success("上传成功");
    }

    private static String getNewFileName(String originalFilename){

        int random = new Random().nextInt(10000);
        StringBuffer name = new StringBuffer();
        name.append(System.currentTimeMillis()).append(random).append(originalFilename);
        return name.toString();
    }
}
